home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1987 / 11 / call.lst < prev    next >
File List  |  1987-10-08  |  16KB  |  463 lines

  1. Listing 1
  2.  
  3.               @Listing 1@.  The @SaveRegion@ Procedure copies any 
  4.               upright rectangular graphics screen region into 
  5.               a buffer, @buff@, where its upper-left (x1,y1) 
  6.               and lower-right (x2,y2) screen coordinates are 
  7.               specified.  GETMEM is used to allocate memory, 
  8.               rather than the standard NEW, because the buffer 
  9.               size needs to be computed at run time. 
  10.  
  11.  
  12.             {The following code is the property of H.D. 
  13.             Callihan, University of Pittsburgh at Johnstown, 
  14.             Johnstown, Pa.  Personal use is encouraged.  Feel 
  15.             free to make copies for distribution to other 
  16.             personal users.  Commercial use is prohibited 
  17.             without written permission and an 
  18.             appropriate license. 
  19.  
  20.             Version:  4     (requires the CRTmode function in 
  21.                             file:  CRTMODE.INC) Purpose:  
  22.                             save and restore a current screen 
  23.                             region in low- or hi-res mode.
  24.                Date:  6/22/87
  25.              Author:  H.D. Callihan, Ph.D.  (C) Copyright 1987
  26.              Applic:  Turbo V3.0 for IBM PC and true compatibles.
  27.                File:  GREGION4.INC
  28.             }
  29.  
  30.  
  31.             TYPE
  32.                 buffermemory = ARRAY[1..3] OF INTEGER;
  33.                 bufferaddress = ^buffermemory;
  34.  
  35.             PROCEDURE SaveRegion(VAR buff : bufferaddress;
  36.                                     x1,y1,  {upper left}
  37.                                     x2,y2   {lower right}
  38.                                           : INTEGER);
  39.              
  40.             {---------- Local functions to SaveRegion-----------}
  41.  
  42.                FUNCTION max(a,b: INTEGER) : INTEGER;
  43.                   BEGIN
  44.                      IF a<b THEN max := b  ELSE max := a
  45.                   END;
  46.  
  47.                FUNCTION min(a,b : INTEGER) : INTEGER;
  48.                   BEGIN
  49.                      IF a<b THEN min := a  ELSE min := b
  50.                   END;
  51.  
  52.             {---------- End local functions --------------------}
  53.  
  54.             VAR   width, height, size : INTEGER;
  55.                       dummy1, dummy2 : BYTE;
  56.  
  57.             BEGIN  {SaveRegion}
  58.  
  59.               {correct for negative x and y} 
  60.               x1 := max(x1,0); x2 := max(x2,0);  
  61.               y1 := max(y1,0); y2 := max(y2,0);
  62.  
  63.               {correct for large y}
  64.               y1 := min(y1,199);  y2 := min(y2,199);         
  65.  
  66.               {compute height of image in pixels}
  67.               height := ABS(y1-y2) +1;
  68.  
  69.               CASE CRTmode(dummy1, dummy2) OF    
  70.                          { dummy1 and dummy2 not used }
  71.                4,5: {one of the low resolutions}
  72.                    BEGIN
  73.                       x1 := min(x1,319);  x2 := min(x2,319);
  74.               
  75.                       {compute width of image in pixels}
  76.                       width := ABS(X1-X2) +1;
  77.  
  78.                       {compute size of buffer need to store image}
  79.                       size := ((width+3) DIV 4) * height * 2  + 6;
  80.  
  81.                       GETMEM(buff, size);
  82.                       GETPIC(buff^, x1,y1,x2,y2)
  83.                    END;
  84.  
  85.                 6: {high resolution}
  86.                   BEGIN
  87.                       x1 := min(x1,639);  x2 := min(x2,639);
  88.                       width := ABS(x1-x2) +1;
  89.                       size := ((width+7) DIV 8) * height  + 6;
  90.                       GETMEM(buff, size);
  91.                       GETPIC(buff^, x1,y1,x2,y2)
  92.                   END;
  93.                 ELSE WRITE(^G); {unacceptable mode}  
  94.               END  {CASE}
  95.             END;  {SaveRegion}
  96.  
  97.  
  98.  
  99.  
  100.  
  101. Listing 2
  102.  
  103.  
  104.             @Listing 2@.  The @CRTmode@ function determines which 
  105.             display mode is currently active.  It returns an integer 
  106.             code as well as two arguments which determine text row 
  107.             and column information if a text mode is active. 
  108.  
  109.  
  110.            FUNCTION CRTmode(VAR  char_columns,
  111.                                  display_page : BYTE) : BYTE;
  112.  
  113.             {Returns CRT mode of operation.  It uses registers and 
  114.             software interrupt 10h to BIOS video services.  Also 
  115.             returns the number of character columns in the current 
  116.             video mode (80 or 40) and the video display page as 
  117.             VARiable parameters. 
  118.  
  119.            Version:  2
  120.             Author:  H. D. Callihan, PhD,  UPJ
  121.               Date:  2/29/87
  122.               File:  CRTMODE.INC
  123.  
  124.            VIDEO MODES:
  125.                0 = 40x25 monochrome
  126.                1 = 40x25 color
  127.                2 = 80x25 monochrome
  128.                3 = 80x25 color
  129.                4 = 320x200 color graphics (40x25 text)
  130.                5 = 320x200 mono graphics  (40x25 text)
  131.                6 = 640x200 b/w high res graphics (80x25 text)
  132.  
  133.             The following values are returned on the AT&T 6300 for 
  134.             superres mode (640x400).
  135.  
  136.              $40 = 640x400 mono superres graphics 
  137.                    (80x25 high quality text)
  138.  
  139.              $48 = 640x400 mono superres graphics 
  140.                    (80x50 tiny text)
  141.  
  142.             Register input :  (AH) <-- 0Fh
  143.             Register output:  (AL) --> current mode
  144.                               (AH) --> number of character 
  145.                                        columns on screen
  146.                               (BH) --> current active display page
  147.  
  148.             Uses software interrupt 10h for BIOS video service.
  149.             }
  150.  
  151.              TYPE regpack = RECORD 
  152.                      ax,bx,cx,dx,bp,si,di,ds,es,flags: INTEGER 
  153.                   END {regpack};
  154.  
  155.              VAR  dosreg : regpack;
  156.  
  157.              BEGIN       {CRTmode}
  158.                 WITH dosreg DO
  159.                    BEGIN       
  160.                      {set high byte $0F for register input}
  161.                      ax := $0F00;            
  162.                           { $0F = 00001111 binary}
  163.  
  164.                      INTR($10, dosreg);   {software interrupt 10h}
  165.                      CRTmode := LO(ax);   {mask low byte}
  166.                      char_columns := HI(ax); {mask high byte}
  167.                      display_page := HI(bx)  {mask high byte}
  168.                    END
  169.              END;       {CRTmode}
  170.  
  171.  
  172.  
  173.  
  174.  
  175. Listing 3
  176.  
  177.  
  178.  
  179.             @Listing 3@.  The @RestoreRegion@ procedure copies any 
  180.             upright rectangular graphics screen region from a 
  181.             buffer, @buff@, previously saved by @SaveRegion@ where 
  182.             its lower-left screen coordinates (x,y) are specified.  
  183.             FREEMEM is used, rather than the standard DISPOSE, 
  184.             because the buffer size needs to be computed at run 
  185.             time. 
  186.  
  187.  
  188.            PROCEDURE RestoreRegion
  189.             (VAR buff : bufferaddress; {pointer}
  190.                       x,y : INTEGER;   {lower left corner}
  191.                    freeup : BOOLEAN);  {freemem after restore}
  192.  
  193.            VAR width, height, resolution, size : INTEGER;
  194.                                     x_ok, y_ok : BOOLEAN;
  195.            BEGIN
  196.               resolution := buff^[1];
  197.               width := buff^[2];
  198.               height := buff^[3];
  199.  
  200.               {check screen boundary y limits}
  201.               y_ok := (y-height+1 >= 0) AND (y < 200);
  202.  
  203.               CASE resolution OF
  204.                 2: {low}
  205.                     BEGIN
  206.                       {check x limits}
  207.                       x_ok := (x >= 0) AND (x+width-1 < 320);
  208.  
  209.                       IF x_ok AND y_ok THEN
  210.                       BEGIN
  211.                          PUTPIC(buff^,x,y);
  212.                          IF freeup THEN
  213.                          BEGIN
  214.                             size := 
  215.                                ((width+3) DIV 4) * height * 2 + 6;
  216.                             FREEMEM(buff, size)
  217.                          END
  218.                       END
  219.                    END;
  220.                1: {high}
  221.                    BEGIN
  222.                       x_ok := (x >= 0) AND (x+width-1 < 640);
  223.                       IF x_ok AND y_ok THEN
  224.                       BEGIN
  225.                          PUTPIC(buff^,x,y);
  226.                          IF freeup THEN {free the buffer}
  227.                          BEGIN
  228.                             size := 
  229.                                ((width+7) DIV 8) * height  + 6;
  230.                             FREEMEM(buff, size)
  231.                          END
  232.                       END
  233.                    END;
  234.                ELSE WRITE(^G^G)
  235.              END  {CASE}
  236.           END;   {RestoreRegion}
  237.  
  238.  
  239.  
  240.  
  241. Listing 4
  242.  
  243.  
  244.             @Listing 4@.  The @FreeBuffer@ procedure permits memory to 
  245.             be freed dynamically without displaying the image on the 
  246.             screen.  Like @RestoreRegion@, it also requires that the 
  247.             size of the memory block be computed based upon the 
  248.             block previously saved by @SaveRegion@. 
  249.          
  250.  
  251.           PROCEDURE FreeBuffer ( VAR buff : bufferaddress );
  252.  
  253.           VAR resolution, width, height, size : INTEGER;
  254.  
  255.           BEGIN
  256.              resolution := buff^[1];
  257.              width := buff^[2];
  258.              height := buff^[3];
  259.  
  260.              CASE resolution OF
  261.                 2 : {LOW}   
  262.                     size := ((width+3) DIV 4) * height * 2 + 6;
  263.                 1 : {HIGH} 
  264.                     size := ((width+7) DIV 8) * height  + 6;
  265.                 ELSE WRITE(^G^G^G)
  266.              END; {CASE}
  267.              IF resolution IN [1,2] THEN FREEMEM(buff, size)
  268.           END;  {FreeBuffer}
  269.  
  270.  
  271.  
  272.  
  273.  
  274. Listing 5
  275.  
  276.  
  277.             @Listing 5@.  The procedure, @SaveBlockToDisk@, facilitates 
  278.             saving a screen region to disk that was previously 
  279.             stored in a memory buffer using @SaveRegion@.  The file 
  280.             name is passed into the procedure as a string argument.  
  281.             @GetBlockFromDisk@ is a procedure which does the opposite 
  282.             by retrieving a block from disk and placing it into 
  283.             contiguous memory located at @buffer@.  @Resolution@ and 
  284.             @size@ are also computed and returned as a matter of 
  285.             convenience.  This recovered region may now be placed 
  286.             onto the screen using @RestoreRegion@. 
  287.  
  288.  
  289.           {H D CALLIHAN, UNIVERSITY OF PGH AT JOHNSTOWN, 1987}
  290.  
  291.           TYPE FileString80 = STRING[80];
  292.           PROCEDURE SaveBlockToDisk 
  293.              ( FileName : FileString80;
  294.                  buffer : bufferaddress  {mem address of block}
  295.              );
  296.  
  297.           VAR
  298.                size, resolution, width, height : INTEGER;
  299.                FileVariable : FILE;              {untyped file}
  300.  
  301.           BEGIN
  302.              resolution := buffer^[1];
  303.              width := buffer^[2];
  304.              height := buffer^[3];
  305.  
  306.              CASE resolution OF
  307.                 1 :  {HIGH}  
  308.                      size := ((width + 7) DIV 8) * height + 6;
  309.                 2 :  {LOW}   
  310.                      size := ((width + 3) DIV 4) * height *2 + 6;
  311.                 ELSE WRITE (^G^G^G^G)
  312.              END;  {CASE}
  313.  
  314.              IF resolution IN [1,2] THEN BEGIN
  315.                 ASSIGN ( FileVariable, FileName );
  316.                 REWRITE ( FileVariable );
  317.                 BLOCKWRITE ( FileVariable, buffer^, 1+(size-1) DIV 128 );
  318.                 CLOSE ( FileVariable )
  319.              END {IF}
  320.           END;  { BlockSave }
  321.  
  322.  
  323.           PROCEDURE GetBlockFromDisk 
  324.               ( FileName   : FileString80;
  325.             VAR buffer     : bufferaddress;
  326.             VAR resolution,  {1=hi, 2=lo}
  327.                 size       : INTEGER );
  328.  
  329.           VAR
  330.              FileVariable : FILE;
  331.              width, height,
  332.              SizeOfFile   : INTEGER;   
  333.                 {number of 128-byte records in block file}
  334.  
  335.           BEGIN
  336.              ASSIGN ( FileVariable, FileName );
  337.              RESET ( FileVariable );
  338.              SizeOfFile := FILESIZE ( FileVariable );
  339.  
  340.              IF SizeOfFile <> 0 THEN BEGIN
  341.                 GETMEM( buffer, SizeOfFile * 128 );
  342.                 BLOCKREAD ( FileVariable, buffer^, SizeOfFile );
  343.                 resolution := buffer^[1];
  344.                 width := buffer^[2];
  345.                 height := buffer^[3];
  346.                 CASE resolution OF
  347.                   1 : {HIGH} 
  348.                       size := ((width+7) DIV 8)*height   +6;
  349.                   2 : {LOW}  
  350.                       size := ((width+3) DIV 4)*height*2 +6;
  351.                   ELSE WRITE(^G^G^G^G^G)
  352.                 END {CASE}
  353.             END;  {IF}
  354.             CLOSE ( FileVariable );
  355.           END;   {GetBlock}
  356.  
  357.  
  358.  
  359.  
  360.  
  361. Listing 6
  362.  
  363.  
  364.             @Listing 6@.  The following program demonstrates the use 
  365.             of @SaveRegion@ and @RestoreRegion@.  Figure 2 contains 
  366.             images saved in @buffer@ and @buffer2@. 
  367.  
  368.  
  369.            PROGRAM Test_SaveRegion_and_RestoreRegion;
  370.  
  371.            {$I graph.p}      {-->   extended Turbo Graphics}
  372.  
  373.            {$I crtmode.inc}  {-->   Callihan function to check 
  374.                                     current crt mode}
  375.            {$I gregion4.inc} {-->   Callihan save and restore 
  376.                                     region Turbo Code
  377.                                     and FreeBuffer code}
  378.  
  379.            VAR        i  : INTEGER;
  380.                 buffer,
  381.                 buffer2  : bufferaddress; 
  382.                   {TYPE declared in the above Callihan file.}
  383.  
  384.                   {The TYPE must be used here for SaveRegion,
  385.                   RestoreRegion, and FreeBuffer to work.   }
  386.  
  387.            BEGIN
  388.               GRAPHCOLORMODE;          {Pick your resolution}
  389.            {   HIRES; }  { use only colors 0 and 1 if this is used}
  390.  
  391.               GRAPHWINDOW(50,100,200,180); 
  392.                    {pick window: (50,100) to (200,180)}
  393.  
  394.               FILLSCREEN(2);
  395.                       {clear current window to green=1, black=0,etc.}
  396.                                                {red=2,  yellow=3 }
  397.  
  398.            {Now, draw lines in black=0, green=1, etc.}
  399.            {draw a nice border around the window}
  400.               DRAW(148,78,148, 2, 3);          
  401.               DRAW(148, 2,  2, 2, 3);
  402.               DRAW(  2, 2,  2,78, 3);
  403.               DRAW(  2,78,148,78, 3);
  404.  
  405.            {Now, let's draw a couple circles in the window 
  406.             with center and radius determined by a loop index. 
  407.             Use color as last parameter.}
  408.  
  409.               FOR i := 10 TO 25 DO CIRCLE(3*i, 2*i, i,  1);
  410.             
  411.               READLN;    {wait for user to press return}
  412.  
  413.               SaveRegion(buffer, 0,0,150,80);
  414.                     {saves in current window coords}
  415.                     {151 pixels wide by 81 high    }
  416.  
  417.            {   GRAPHCOLORMODE;}   {this call clears and resets
  418.                                    window to full screen}
  419.  
  420.               FILLSCREEN(0);      {clear window to black, 
  421.                                    don't reset to full screen}
  422.  
  423.               READLN;
  424.  
  425.               RestoreRegion(buffer,0,80,false); 
  426.                    {Restores in current window coords }
  427.                    {at the lower left point 0,80      }
  428.                    {but does not free the buffer.     }
  429.  
  430.               READLN;
  431.  
  432.               GRAPHCOLORMODE;     {Pick resolution again}
  433.            {   HIRES;}
  434.  
  435.               RestoreRegion(buffer,0,80,false);
  436.  
  437.               READLN;
  438.  
  439.               FOR i := 1 TO 10 DO 
  440.                   {let's get fancy}
  441.                   RestoreRegion(buffer,
  442.                            150 - 8*i, 200 - 10*i, false);
  443.               READLN;
  444.  
  445.               SaveRegion(buffer2,0,0,319,199); 
  446.                       {Use buffer2 for background}
  447.  
  448.               FILLSCREEN(0);
  449.  
  450.               FOR i := 1 TO 10 DO BEGIN
  451.                  RestoreRegion(buffer, 10+4*i, 200-5*i, false);
  452.                  READLN;
  453.  
  454.                  RestoreRegion(buffer2,0,199,false) 
  455.                        {Restore background}
  456.               END;  {for}
  457.  
  458.               READLN;
  459.  
  460.               TEXTMODE    {Return to the standard text screen}
  461.  
  462.            END.
  463.